namespace SimpleTPL;

using System;
using System.Runtime.CompilerServices;

public interface IAsyncStateMachine
{
    void MoveNext();
}
public class SimpleAsyncMethodBuilder<TResult>
{
    private SimpleTask<TResult> _task;
    private Exception _exception;
    private TResult _result;
    private bool _hasResult;

    public static SimpleAsyncMethodBuilder<TResult> Create() => new SimpleAsyncMethodBuilder<TResult>();

    public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
    {
        // 使用本地变量捕获状态机
        var boxedStateMachine = (IAsyncStateMachine)stateMachine;
        var task = _task = new SimpleTask<TResult>(() => 
        {
            boxedStateMachine.MoveNext();
            return _hasResult ? _result : default;
        });
        SimpleThreadPool.UnsafeQueueUserWorkItem(_ => {
            boxedStateMachine.MoveNext();
            task.Execute();
        });
    }

    public void SetException(Exception exception)
    {
        _exception = exception;
        _task?.SetException(exception);
    }

    public void SetResult(TResult result)
    {
        _result = result;
        _hasResult = true;
        _task?.SetResult(result);
    }

    public void AwaitOnCompleted<TAwaiter, TStateMachine>(
        ref TAwaiter awaiter, TStateMachine stateMachine)
        where TAwaiter : INotifyCompletion
        where TStateMachine : IAsyncStateMachine
    {
        awaiter.OnCompleted(stateMachine.MoveNext);
    }

    public SimpleTask<TResult> Task => _task ??= new SimpleTask<TResult>(() => _result);
}
